package org.kl.bpm.listener;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.impl.context.Context;
import org.kl.bpm.rule.AssigneeRule;
import org.kl.bpm.rule.PositionAssigneeRule;
import org.kl.bpm.rule.RuleMatcher;
import org.kl.bpm.rule.SuperiorAssigneeRule;
import org.kl.bpm.rule.UserAssigneeRule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

public class AssigneeAliasTaskListener extends DefaultTaskListener {
	private static final long serialVersionUID = -619874857391855407L;
	private static Logger logger = LoggerFactory.getLogger(AssigneeAliasTaskListener.class);
	@SuppressWarnings("unused")
	private JdbcTemplate jdbcTemplate;
	private Map<RuleMatcher, AssigneeRule> assigneeRuleMap = new HashMap<RuleMatcher, AssigneeRule>();

	public AssigneeAliasTaskListener() {
		SuperiorAssigneeRule superiorAssigneeRule = new SuperiorAssigneeRule();
		PositionAssigneeRule positionAssigneeRule = new PositionAssigneeRule();
		UserAssigneeRule userAssigneeRule = new UserAssigneeRule();
		assigneeRuleMap.put(new RuleMatcher("常用语"), superiorAssigneeRule);
		assigneeRuleMap.put(new RuleMatcher("岗位"), positionAssigneeRule);
		assigneeRuleMap.put(new RuleMatcher("人员"), userAssigneeRule);
	}

	@Override
	public void onCreate(DelegateTask delegateTask) throws Exception {
		String assignee = delegateTask.getAssignee();
		logger.debug("assignee : {}", assignee);
		if (assignee != null) {
			for (Map.Entry<RuleMatcher, AssigneeRule> entry : assigneeRuleMap.entrySet()) {
				RuleMatcher ruleMatcher = entry.getKey();

				if (!ruleMatcher.matches(assignee)) {
					continue;
				}

				String value = ruleMatcher.getValue(assignee);
				AssigneeRule assigneeRule = entry.getValue();
				logger.debug("value : {}", value);
				logger.debug("assigneeRule : {}", assigneeRule);

				if (assigneeRule instanceof SuperiorAssigneeRule) {
					this.processSuperior(delegateTask, assigneeRule, value);
				} else if (assigneeRule instanceof PositionAssigneeRule) {
					this.processPosition(delegateTask, assigneeRule, value);
				} else if (assigneeRule instanceof UserAssigneeRule) {
					this.processUser(delegateTask, assigneeRule, value);
				}
			}
		}
	}

	public void processSuperior(DelegateTask delegateTask, AssigneeRule assigneeRule, String value) {
		String processInstanceId = delegateTask.getProcessInstanceId();
		String startUserId = Context.getCommandContext().getHistoricProcessInstanceEntityManager()
				.findHistoricProcessInstance(processInstanceId).getStartUserId();
		String userId = assigneeRule.process(startUserId);
		logger.debug("userId : {}", userId);
		delegateTask.setAssignee(userId);
	}

	public void processPosition(DelegateTask delegateTask, AssigneeRule assigneeRule, String value) {
		String processInstanceId = delegateTask.getProcessInstanceId();
		String startUserId = Context.getCommandContext().getHistoricProcessInstanceEntityManager()
				.findHistoricProcessInstance(processInstanceId).getStartUserId();
		List<String> userIds = assigneeRule.process(value, startUserId);
		logger.debug("userIds : {}", userIds);

		if (!userIds.isEmpty()) {
			delegateTask.setAssignee(userIds.get(0));
		}
	}

	public void processUser(DelegateTask delegateTask, AssigneeRule assigneeRule, String value) {
		String userId = assigneeRule.process(value);
		logger.debug("userId : {}", userId);

		if (!userId.isEmpty()) {
			delegateTask.setAssignee(userId);
		}
	}

	@Resource
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
}
